/*
 *  Created on: May 17, 2009
 *      Author: Ramesh Rajaby
 */


#ifndef _SYMPHONY_BYTECODE_STRUCTURES_
#define _SYMPHONY_BYTECODE_STRUCTURES_


#include "../Shared.h"
#include "../AST/AST.h"

namespace SymphonyBC {


class InstructionBC {
public:
	OpCode opcode;
	StackPointer op1, op2, op3;

	InstructionBC() {
		op1 = op2 = op3 = 0;
	}
};


class Softlink {
public:
	string refName;
	int objectType;
	int methodIndex;
	int instrPtr;
	int operand;

	Softlink() {}

	Softlink(string refName, int objectType, int methodIndex, int instrPtr, int operand) {
		this->refName = refName;
		this->objectType = objectType;
		this->methodIndex = methodIndex;
		this->instrPtr = instrPtr;
		this->operand = operand;
	}
};


class MemberBC {
private:
	int type;
	string name;

public:
	string getName() {
		return name;
	}
	void setName(const string& name) {
		this->name = name;
	}

	int getType() {
		return type;
	}
	void setType(int type) {
		this->type = type;
	}
};


class MethodBC {
private:
	vector<InstructionBC*> instructions;
	string name;
	int returnType;

public:
	string getName() {
		return name;
	}
	void setName(const string& name) {
		this->name = name;
	}

	int getReturnType() {
		return returnType;
	}
	void setReturnType(int returnType) {
		this->returnType = returnType;
	}

	void addInstruction(InstructionBC* instruction) {
		instructions.push_back(instruction);
	}
	InstructionBC* getInstruction(int i) {
		return instructions[i];
	}

	vector<InstructionBC*> getInstructions() {
		return instructions;
	}
};


class ClassBC {
private:
	vector<MemberBC*> members;
	vector<MethodBC*> methods;
	string name;
	string dataArea;
	vector<Softlink*> softlinks;
	vector<string> loadedClasses;

public:
	string getName() {
		return name;
	}
	void setName(const string& name) {
		this->name = name;
	}

	void addMember(const string& name, MemberBC* member) {
		members.push_back(member);
	}
	MemberBC* getMember(int id) {
		return members[id];
	}
	vector<MemberBC*> getMembers() {
		return members;
	}

	void addMethod(const string& name, MethodBC* method) {
		methods.push_back(method);
	}
	MethodBC* getMethod(int id) {
		return methods[id];
	}
	vector<MethodBC*> getMethods() {
		return methods;
	}

    string getDataArea() const {
        return dataArea;
    }
    void setDataArea(string dataArea) {
        this->dataArea = dataArea;
    }

    int addSoftlink(Softlink* softlink) {
    	softlinks.push_back(softlink);
    	return softlinks.size()-1;
    }
    vector<Softlink*> getSoftlinks() {
    	return softlinks;
    }

    void addLoadedClass(string loadedClass) {
    	loadedClasses.push_back(loadedClass);
    }
    vector<string> getLoadedClasses() {
    	return loadedClasses;
    }
};


}


#endif
